package com.glodon.paas.document;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.glodon.paas.document.constant.DocumentConstant;
import com.glodon.paas.document.dao.FileDao;
import com.glodon.paas.document.dao.MultiPartUploadHandleDao;
import com.glodon.paas.document.dao.PartDao;
import com.glodon.paas.document.dao.RevisionDao;
import com.glodon.paas.document.dao.ShareDao;
import com.glodon.paas.document.dao.domain.FileInfoEntity;
import com.glodon.paas.document.dao.domain.RevisionEntity;
import com.glodon.paas.document.dao.domain.ShareEntity;
import com.glodon.paas.storage.BulkStorage;

public abstract class DocumentBaseIT {

    public static final boolean           testPerformance = false;

    public static final String            ownerId         = "ThisIsTestOwnerId";

    public static final String            userId          = "ThisIsTestUserId";
    
    public static final String            adminId          = "ThisIsAdminUserId";
    
    public static final String            enterId          = "ThisIsEnterUserId";
    
    public static final String            readId          = "ThisIsReadUserId";
    
    public static final String            writeId          = "ThisIsWriteUserId";
    
    public static final String            deleteId          = "ThisIsDeleteUserId";
    
    public static final String            unassignedId          = "ThisIsUnassignedUserId";

    protected static final String         fileIdPre       = "ThisIsTestFileId";

    protected static final String         fileId1         = "ThisIsTestFileId" + 1;

    protected static List<FileInfoEntity> files           = new ArrayList<FileInfoEntity>();

    protected static final Long           fileSize        = BulkStorage.BLOCK_SIZE * 2;

    protected static final String         shareIdPre      = "ThisIsTestShareId";

    protected static List<ShareEntity>    shares          = new ArrayList<ShareEntity>();

    protected static boolean              initedData      = false;

    @Autowired
    protected ShareDao                    shareDao;

    @Autowired
    protected FileDao                     fileDao;

    @Autowired
    protected RevisionDao                 revisionDao;

    @Autowired
    protected PartDao                     partDao;

    @Autowired
    protected MultiPartUploadHandleDao    handlerDao;

    protected void setup() {
        createFolder(1);
        createDoc(2);
        removeFile(3);
        fileDao.insert(newFile(fileIdPre + 3, fileIdPre + 1, "ThisIsSubFile", "txt", ownerId,
                               DocumentConstant.FILE_TYPE_FILE));
        initedData = true;
    }

    // file start
    protected FileInfoEntity createDoc(int idNum) {
        fileDao.delete(fileIdPre + idNum);
        FileInfoEntity file = newFile(fileIdPre + idNum, ownerId, "file" + idNum, "txt", ownerId,
                                      DocumentConstant.FILE_TYPE_FILE);
        file.setSize(fileSize);
        fileDao.insert(file);
        files.add(file);
        return file;
    }

    protected FileInfoEntity createFolder(int idNum) {
        fileDao.delete(fileIdPre + idNum);
        FileInfoEntity file = newFile(fileIdPre + idNum, ownerId, "folder" + idNum, "", ownerId, DocumentConstant.FILE_TYPE_FOLDER);
        fileDao.insert(file);
        files.add(file);
        return file;
    }

    protected void removeFile(int idNum) {
        fileDao.delete(fileIdPre + idNum);
        if (files.size() >= idNum) {
            files.remove(idNum - 1);
        }
    }

    protected static FileInfoEntity newFile(String id, String parentId, String name, String extension, String ownerId, Integer type) {
        FileInfoEntity file = new FileInfoEntity();
        file.setId(id);
        file.setParentId(parentId);
        file.setName(name);
        file.setExtension(extension);
        file.setOwnerId(ownerId);
        file.setCreateTime(new Date());
        file.setCreator(ownerId);
        file.setUpdator(ownerId);
        file.setType(type);
        file.setActiveRevision(1);
        return file;
    }

    public void cleanFile() {
        cleanRevision();
        fileDao.cleanByOwnerId(ownerId);
        files.clear();
    }

    private void cleanRevision() {
        List<FileInfoEntity> files = fileDao.getFiles(ownerId, null, null, null);
        for (FileInfoEntity file : files) {
            RevisionEntity v = revisionDao.getLatestUnavailableRevision(file.getId());
            if (v != null) {
                partDao.delParts(v.getId());
                handlerDao.delete(v.getId());
            }
            revisionDao.deleteByFile(file.getId());
        }
    }

    // file end

    // share start
    protected ShareEntity createShare(int idNum) {
        shareDao.delete(shareIdPre + idNum);
        ShareEntity share = newShare(shareIdPre + idNum, fileIdPre + idNum, ownerId, userId);
        shares.add(share);
        shareDao.insert(share);
        fileDao.updateShareType(fileIdPre + idNum, DocumentConstant.SHARE_TYPE_SHARED);
        return share;
    }

    protected void removeShare(int idNum) {
        shareDao.delete(shareIdPre + idNum);
        fileDao.updateShareType(fileIdPre + idNum, DocumentConstant.SHARE_TYPE_NORMAL);
        if (shares.size() >= idNum) {
            shares.remove(idNum - 1);
        }
    }

    protected static ShareEntity newShare(String id, String fileId, String ownerId, String userId) {
        ShareEntity share = new ShareEntity();
        share.setId(id);
        share.setFileId(fileId);
        share.setCreatedTime(new Date());
        share.setPrivilege(DocumentConstant.SHARE_PRIVILEGE_READ);
        share.setSharedUserId(ownerId);
        share.setToUserId(userId);
        share.setShareType(DocumentConstant.SHARE_TYPE_SHARED);
        return share;
    }

    public void cleanShare() {
        shareDao.deleteByOwner(ownerId);
        shares.clear();
    }

    // share end
}
